Printing and checking the WOLF tree
The wolf tree is a powerful data structure where all the problem is organized.
You can print it on the Terminal with different levels of detail, which are customizable
through the API.
This gives you the opportunity to look at how WOLF is book-keeping all the information. You can use it to debug your developments, or to tune your algorithms.
Similarly, we have a method check that performs a thorough check of all the pointers in the tree
to ensure that every node is properly connected.
The method Problem::print()
The method to call resides in Problem:
class Problem [...]
{
public:
/**
* \brief print wolf tree
* \param depth : levels to show ( 0: H, T, M : 1: H:S, T:F, M:L ; 2: H:S:p, T:F:C ; 3: T:F:C:f ; 4: T:F:C:f:c )
* \param constr_by: show factors pointing to F, f and L.
* \param metric : show metric info (status, time stamps, state vectors, measurements)
* \param state_blocks : show state blocks
*/
void print(int depth = 4,
bool constr_by = false,
bool metric = true,
bool state_blocks = false,
std::ostream& stream = std::cout) const;
}
The inlined documentation is enough for an API recall.
For a complete demonstration of how print(...) works, read on.
The input parameters of print() are documented as follows
depth: The depth of the printed result.0: print only Hardware, Trajectory and Map2: print also Captures and Processors3: print also Features4: print also Factors
constr_by: print which factors point to each node of the treemetric: print metric values for all states and measurementsstate_blocks: print information about each state block individually
In order to correctly interpret the outcome, you just need to know a few mnemotechnics to identify the nodes:
P: ProblemH: HardwareT: TrajectoryM: MapS, Sen: Sensorp, Prc: ProcessorF, Frm: FrameC, Cap: Capturef, Ftr: Featurec, Fac: Factor
Examples
Simplest print
print(0,0,0,0);
Even with such a short print, we see that we have two sensors, two frames and four landmarks:
Wolf tree status ------------------------
Hardware -- 2S
Trajectory -- 2F
Map -- 4L
-----------------------------------------
First level depth
print(1,0,0,0);
We start seeing some detail:
Each sensor has a type and name, and has one processor.
The frame structure is POV, and we have their time stamps, and how many Captures each.
We also see the type of landmarks.
Wolf tree status ------------------------
Hardware
Sen1 SensorCamera "CAMERA" -- 1p
Sen2 SensorImu "IMU" -- 1p
Trajectory
Frm1 POV ts = 0.000000000 -- 3C
Frm8 POV ts = 0.300000000 -- 1C
Map
Lmk50 LandmarkApriltag
Lmk52 LandmarkApriltag
Lmk54 LandmarkApriltag
Lmk56 LandmarkApriltag
-----------------------------------------
Second level depth
print(2,0,0,0);
The tree details are growing!
We see some status of the processors, with the origin and last captures, and to which frame they are attached.
We see the size of the motion data buffer in captures of type CaptureMotion.
We see the number of features of each capture.
Wolf tree status ------------------------
Hardware
Sen1 SensorCamera "CAMERA"
PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
o: Cap71 - Frm8
l: Cap128 - Frm13
Sen2 SensorImu "IMU"
PrcM2 ProcessorImu "IMU PROC"
o: Cap85 - Frm8
l: Cap4 - Frm2
Trajectory
Frm1 POV ts = 0.000000000
Cap2 CaptureVoid ts = 0.000000000 -> Sen- -- 3f
CapM3 CaptureImu ts = 0.000000000 -> Sen2 -- 0f
buffer size : 0
Cap9 CaptureImage ts = 0.000000000 -> Sen1 -- 0f
Frm8 POV ts = 0.300000000
Cap71 CaptureImage ts = 0.300000000 -> Sen1 -- 4f
CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1 -- 1f
buffer size : 62 ; nbr of data samples : 61
Map
Lmk50 LandmarkApriltag
Lmk52 LandmarkApriltag
Lmk54 LandmarkApriltag
Lmk56 LandmarkApriltag
-----------------------------------------
Full depth
Let us show the full tree structure
print(4,0,0,0);
Now we see all the way down to the Features and Factors!
For each Feature, we can see the track it has been associated to
For each Factor, we see after the arrow
-->the nodes it is pointing to.Some Factors do not point anywhere, because they are absolute. We mark this with
Abs.
Of course, you can also
print(3,0,0,0)and stop at the Feature level.
Wolf tree status ------------------------
Hardware
Sen1 SensorCamera "CAMERA"
PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
o: Cap71 - Frm8
l: Cap83 - Frm9
Sen2 SensorImu "IMU"
PrcM2 ProcessorImu "IMU PROC"
o: Cap85 - Frm8
l: Cap4 - Frm2
Trajectory
Frm1 POV ts = 0.000000000
Cap2 CaptureVoid ts = 0.000000000 -> Sen-
Ftr1 trk0 Prior V
Fac1 FactorBlockAbsolute --> Abs
Ftr2 trk0 Prior O
Fac2 FactorQuaternionAbsolute --> Abs
Ftr3 trk0 Prior P
Fac3 FactorBlockAbsolute --> Abs
CapM3 CaptureImu ts = 0.000000000 -> Sen2
buffer size : 0
Cap9 CaptureImage ts = 0.000000000 -> Sen1
Frm8 POV ts = 0.300000000
Cap71 CaptureImage ts = 0.300000000 -> Sen1
Ftr24 trk50 FeatureApriltag
Fac4 FactorApriltag --> Lmk50
Ftr25 trk52 FeatureApriltag
Fac5 FactorApriltag --> Lmk52
Ftr26 trk54 FeatureApriltag
Fac6 FactorApriltag --> Lmk54
Ftr27 trk56 FeatureApriltag
Fac7 FactorApriltag --> Lmk56
CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1
buffer size : 62 ; nbr of data samples : 61
Ftr32 trk0 FeatureImu
Fac8 FactorImu --> Frm1 Cap3
Map
Lmk50 LandmarkApriltag
Lmk52 LandmarkApriltag
Lmk54 LandmarkApriltag
Lmk56 LandmarkApriltag
-----------------------------------------
Metric information
Let us add the metric information for states and measurements
print(3,0,1,0);
We now see the state values of:
Sensors: extrinsic and intrinsic parameters
Frames: robot position, orientation and velocity
Captures: in those of type IMU, the intrinsic sensor values, that is, the time-varying IMU biases!
Landmarks: position and orientation
Also,
the measurements contained in each Feature!
Wolf tree status ------------------------
Hardware
Sen1 SensorCamera "CAMERA"
Fix, x = ( 0 0 0 0 0 0 1 320 240 320 320 )
PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
o: Cap71 - Frm8
l: Cap83 - Frm9
Sen2 SensorImu "IMU"
Est, x = ( 0 0 0 0 0 0 1 0 0 0 0 0 0 )
PrcM2 ProcessorImu "IMU PROC"
o: Cap85 - Frm8
l: Cap4 - Frm2
Trajectory
Frm1 POV ts = 0.000000000
Est, x = ( 0 0 0 1 0 0 0 0 0 0 )
Cap2 CaptureVoid ts = 0.000000000 -> Sen-
Ftr1 trk0 Prior V -- 1c
m = ( 0 0 0 )
Ftr2 trk0 Prior O -- 1c
m = ( 1 0 0 0 )
Ftr3 trk0 Prior P -- 1c
m = ( 0 0 0 )
CapM3 CaptureImu ts = 0.000000000 -> Sen2
Est, x = ( 0 0 0 0 0 0 )
buffer size : 0
Cap9 CaptureImage ts = 0.000000000 -> Sen1
Frm8 POV ts = 0.300000000
Est, x = ( 0.000343 -0.00354 1.11e-16 1 0 0 0 0.00339 -0.0235 8.88e-16 )
Cap71 CaptureImage ts = 0.300000000 -> Sen1
Ftr24 trk50 FeatureApriltag -- 1c
m = ( 0.046 0.6 1 0 0 0 1 )
Ftr25 trk52 FeatureApriltag -- 1c
m = ( 0.046 0.097 1 7.4e-07 -2.6e-07 -3.4e-08 1 )
Ftr26 trk54 FeatureApriltag -- 1c
m = ( 0.55 0.097 1 1.2e-07 8.7e-08 -6.8e-08 1 )
Ftr27 trk56 FeatureApriltag -- 1c
m = ( 0.55 -0.4 1 7.1e-08 5.2e-08 -3.9e-08 1 )
CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1
Est, x = ( 0 0 0 0 0 0 )
buffer size : 62 ; nbr of data samples : 61
delta preint : (0.000343 0.00354 -0.441 0 0 0 1 0.00339 0.0235 -2.94)
Ftr32 trk0 FeatureImu -- 1c
m = ( 0.00034 0.0035 -0.44 0 0 0 1 0.0034 0.024 -2.9 )
Map
Lmk50 LandmarkApriltag
Est, x = ( 0.0465 -0.597 -1 1 0 0 0 )
Lmk52 LandmarkApriltag
Est, x = ( 0.0465 -0.0971 -1 1 3.44e-08 -2.6e-07 -7.4e-07 )
Lmk54 LandmarkApriltag
Est, x = ( 0.546 -0.0971 -1 1 6.8e-08 8.7e-08 -1.25e-07 )
Lmk56 LandmarkApriltag
Est, x = ( 0.546 0.403 -1 1 3.86e-08 5.21e-08 -7.06e-08 )
-----------------------------------------
State blocks structure
Let us explore such states deeper, by showing the structure of state-blocks:
print(2,0,0,1);
All the state structure is now clearly displayed, showing the semantinc meaning of each part:
P: positionO: orientationV: velocityI: intrinsic parameters –> IMU biases
We can see the role of each state block in the estimation
[Est]means the block is estimated[Fix]means the block is fixed
Also, we see the address value of the pointer to each state block. This might be useful to debug the interface with the solver, which might be using such pointers.
Wolf tree status ------------------------
Hardware
Sen1 SensorCamera "CAMERA"
sb: P [Fix] @ 0x5603407aaae0 O [Fix] @ 0x5603407abf50 I [Fix] @ 0x5603407ab8e0
PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
o: Cap72 - Frm8
l: Cap117 - Frm12
Sen2 SensorImu "IMU"
sb: P [Fix] @ 0x5603407ab160 O [Fix] @ 0x5603407ab0a0 I [Est] @ 0x560340e85690
PrcM2 ProcessorImu "IMU PROC"
o: Cap85 - Frm8
l: Cap4 - Frm2
Trajectory
Frm1 POV ts = 0.000000000
sb: P [Est] @ 0x56034076f6a0 O [Est] @ 0x560340771c70 V [Est] @ 0x560340773560
Cap2 CaptureVoid ts = 0.000000000 -> Sen- -- 3f
CapM3 CaptureImu ts = 0.000000000 -> Sen2 -- 0f
sb: I [Est] @ 0x56034076c760
buffer size : 0
Cap8 CaptureImage ts = 0.000000000 -> Sen1 -- 3f
Frm8 POV ts = 0.300000000
sb: P [Est] @ 0x7ff7d00267d0 O [Est] @ 0x7ff7b0016540 V [Est] @ 0x7ff7c001f540
Cap72 CaptureImage ts = 0.300000000 -> Sen1 -- 4f
CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1 -- 1f
sb: I [Est] @ 0x560340e85690
buffer size : 62 ; nbr of data samples : 61
Map
Lmk50 LandmarkApriltag
sb: P [Est] @ 0x7ff7c001e3d0 O [Est] @ 0x56034077c140
Lmk54 LandmarkApriltag
sb: P [Est] @ 0x560340769040 O [Est] @ 0x56034077c2f0
Lmk56 LandmarkApriltag
sb: P [Est] @ 0x560340e84810 O [Est] @ 0x560340e853d0
Lmk52 LandmarkApriltag
sb: P [Est] @ 0x7ff7d00254b0 O [Est] @ 0x7ff7a80227e0
-----------------------------------------
We can also combine state_block and metric options, and observe the state-block structure alongside the state values,
print(2,0,1,1);
which results in
Wolf tree status ------------------------
Hardware
Sen1 SensorCamera "CAMERA"
P [Fix] = ( 0 0 0 ) @ 0x5633405c0c80
O [Fix] = ( 0 0 0 1 ) @ 0x5633405c20f0
I [Fix] = ( 320 240 320 320 ) @ 0x5633405c1a80
PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
o: Cap71 - Frm8
l: Cap128 - Frm13
Sen2 SensorImu "IMU"
P [Fix] = ( 0 0 0 ) @ 0x5633405c1300
O [Fix] = ( 0 0 0 1 ) @ 0x5633405c1240
I [Est] = ( 3.77e-08 3.76e-07 3.84e-11 -2.13e-06 2.13e-07 7.13e-07 ) @ 0x563340bc1830
PrcM2 ProcessorImu "IMU PROC"
o: Cap85 - Frm8
l: Cap4 - Frm2
Trajectory
Frm1 POV ts = 0.000000000
P [Est] = ( -2.67e-17 2.66e-16 3.76e-21 ) @ 0x563340585900
O [Est] = ( 1 3.61e-13 9.17e-12 9.15e-11 ) @ 0x563340587ed0
V [Est] = ( -1.26e-09 1.26e-08 1.03e-13 ) @ 0x5633405897c0
Cap2 CaptureVoid ts = 0.000000000 -> Sen- -- 3f
CapM3 CaptureImu ts = 0.000000000 -> Sen2 -- 0f
I [Est] = ( 3.77e-08 3.76e-07 3.84e-11 -2.13e-06 2.13e-07 7.13e-07 ) @ 0x5633405829c0
buffer size : 0
Cap9 CaptureImage ts = 0.000000000 -> Sen1 -- 0f
Frm8 POV ts = 0.300000000
P [Est] = ( 0.000343 -0.00354 -7.41e-10 ) @ 0x563340c928d0
O [Est] = ( 1 1.07e-07 -3.2e-08 -3.19e-07 ) @ 0x7f27f8011ec0
V [Est] = ( 0.00339 -0.0235 -7.49e-09 ) @ 0x7f27f401bd70
Cap71 CaptureImage ts = 0.300000000 -> Sen1 -- 4f
CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1 -- 1f
I [Est] = ( 3.77e-08 3.76e-07 3.84e-11 -2.13e-06 2.13e-07 7.13e-07 ) @ 0x563340bc1830
buffer size : 62 ; nbr of data samples : 61
delta preint : (0.000343 0.00354 -0.441 0 0 0 1 0.00339 0.0235 -2.94)
Map
Lmk50 LandmarkApriltag
P [Est] = ( 0.0468 -0.6 -1 ) @ 0x7f2804024f70
O [Est] = ( 1 1.07e-07 -3.2e-08 -3.19e-07 ) @ 0x563340c91750
Lmk52 LandmarkApriltag
P [Est] = ( 0.0468 -0.1 -1 ) @ 0x56334059a3c0
O [Est] = ( 1 1.41e-07 -2.92e-07 -1.06e-06 ) @ 0x563340c91650
Lmk54 LandmarkApriltag
P [Est] = ( 0.547 -0.1 -1 ) @ 0x7f2804022050
O [Est] = ( 1 1.75e-07 5.5e-08 -4.43e-07 ) @ 0x7f27f0002bc0
Lmk56 LandmarkApriltag
P [Est] = ( 0.547 0.4 -1 ) @ 0x563340be9810
O [Est] = ( 1 1.46e-07 2.01e-08 -3.9e-07 ) @ 0x5633401f0060
-----------------------------------------
Factors connectivity
Now let us show how Factors point to different nodes of the tree:
print(4,1,0,0);
We observe this information in two ways:
From each Factor, we see an outgoing arrow
-->pointing to each node of the tree that concerns it.Factors can point to Sensors, Frames, Captures, Features and Landmarks.
Some factors do not point anywhere, because they are absolute. We mark it with
Abs.
To each node of the tree, we see an incoming arrow
<--with all Factors pointing to it.Logically, we want these correspondences to match in all cases:
If a factor
Facpoints to a nodeN,Fac --> N, then alsoNneeds to be pointed byFac,N <-- Fac.Also, some nodes are not yet pointed by any factor. We see a dangling
<--arrow.
Wolf tree status ------------------------
Hardware
Sen1 SensorCamera "CAMERA"
PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
o: Cap205 - Frm20
l: Cap216 - Frm21
Sen2 SensorImu "IMU"
PrcM2 ProcessorImu "IMU PROC"
o: Cap218 - Frm20
l: Cap4 - Frm2
Trajectory
Frm1 POV ts = 0.000000000 <-- Fac8
Cap2 CaptureVoid ts = 0.000000000 -> Sen- <--
Ftr1 trk0 Prior V -- 1c <--
Ftr2 trk0 Prior O -- 1c <--
Ftr3 trk0 Prior P -- 1c <--
CapM3 CaptureImu ts = 0.000000000 -> Sen2 <-- Fac8
buffer size : 0
Cap9 CaptureImage ts = 0.000000000 -> Sen1 <--
Frm8 POV ts = 0.300000000 <-- Fac13
Cap71 CaptureImage ts = 0.300000000 -> Sen1 <--
Ftr24 trk50 FeatureApriltag -- 1c <--
Ftr25 trk52 FeatureApriltag -- 1c <--
Ftr26 trk54 FeatureApriltag -- 1c <--
Ftr27 trk56 FeatureApriltag -- 1c <--
CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1 <-- Fac13
buffer size : 62 ; nbr of data samples : 61
Ftr32 trk0 FeatureImu -- 1c <--
Frm14 POV ts = 0.600000000 <-- Fac18
Cap140 CaptureImage ts = 0.600000000 -> Sen1 <--
Ftr49 trk50 FeatureApriltag -- 1c <--
Ftr50 trk52 FeatureApriltag -- 1c <--
Ftr51 trk54 FeatureApriltag -- 1c <--
Ftr52 trk56 FeatureApriltag -- 1c <--
CapM152 CaptureImu ts = 0.600000000 -> Sen2 -> Origin: Cap85 ; Frm8 <-- Fac18
buffer size : 61 ; nbr of data samples : 60
Ftr57 trk0 FeatureImu -- 1c <--
Frm20 POV ts = 0.900000000 <--
Cap205 CaptureImage ts = 0.900000000 -> Sen1 <--
Ftr74 trk50 FeatureApriltag -- 1c <--
Ftr75 trk52 FeatureApriltag -- 1c <--
Ftr76 trk54 FeatureApriltag -- 1c <--
Ftr77 trk56 FeatureApriltag -- 1c <--
CapM218 CaptureImu ts = 0.900000000 -> Sen2 -> Origin: Cap152 ; Frm14 <--
buffer size : 61 ; nbr of data samples : 60
Ftr82 trk0 FeatureImu -- 1c <--
Map
Lmk50 LandmarkApriltag <-- Fac4 Fac9 Fac14
Lmk52 LandmarkApriltag <-- Fac5 Fac10 Fac15
Lmk54 LandmarkApriltag <-- Fac6 Fac11 Fac16
Lmk56 LandmarkApriltag <-- Fac7 Fac12 Fac17
-----------------------------------------
Full print
Let us finally activate all options!
print(4,1,1,1);
A full print might be overwhelming!
Wolf tree status ------------------------
Hardware
Sen1 SensorCamera "CAMERA"
P [Fix] = ( 0 0 0 ) @ 0x55e3cb82dc80
O [Fix] = ( 0 0 0 1 ) @ 0x55e3cb82f0f0
I [Fix] = ( 320 240 320 320 ) @ 0x55e3cb82ea80
PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
o: Cap71 - Frm8
l: Cap83 - Frm9
Sen2 SensorImu "IMU"
P [Fix] = ( 0 0 0 ) @ 0x55e3cb82e300
O [Fix] = ( 0 0 0 1 ) @ 0x55e3cb82e240
I [Est] = ( 0 0 0 0 0 0 ) @ 0x55e3cbe2e110
PrcM2 ProcessorImu "IMU PROC"
o: Cap85 - Frm8
l: Cap4 - Frm2
Trajectory
Frm1 POV ts = 0.000000000 <-- Fac8
P [Est] = ( 0 0 0 ) @ 0x55e3cb7f2900
O [Est] = ( 1 0 0 0 ) @ 0x55e3cb7f4ed0
V [Est] = ( 0 0 0 ) @ 0x55e3cb7f67c0
Cap2 CaptureVoid ts = 0.000000000 -> Sen- <--
Ftr1 trk0 Prior V <--
m = ( 0 0 0 )
Fac1 FactorBlockAbsolute --> Abs
Ftr2 trk0 Prior O <--
m = ( 1 0 0 0 )
Fac2 FactorQuaternionAbsolute --> Abs
Ftr3 trk0 Prior P <--
m = ( 0 0 0 )
Fac3 FactorBlockAbsolute --> Abs
CapM3 CaptureImu ts = 0.000000000 -> Sen2 <-- Fac8
I [Est] = ( 0 0 0 0 0 0 ) @ 0x55e3cb7ef9c0
buffer size : 0
Cap10 CaptureImage ts = 0.000000000 -> Sen1 <--
Frm8 POV ts = 0.300000000 <--
P [Est] = ( 0.000343 -0.00354 1.11e-16 ) @ 0x55e3cbeff930
O [Est] = ( 1 0 0 0 ) @ 0x7fdfd001efd0
V [Est] = ( 0.00339 -0.0235 8.88e-16 ) @ 0x7fdfd8010350
Cap71 CaptureImage ts = 0.300000000 -> Sen1 <--
Ftr24 trk50 FeatureApriltag <--
m = ( 0.046 0.6 1 0 0 0 1 )
Fac4 FactorApriltag --> Lmk50
Ftr25 trk52 FeatureApriltag <--
m = ( 0.046 0.097 1 7.4e-07 -2.6e-07 -3.4e-08 1 )
Fac5 FactorApriltag --> Lmk52
Ftr26 trk54 FeatureApriltag <--
m = ( 0.55 0.097 1 1.2e-07 8.7e-08 -6.8e-08 1 )
Fac6 FactorApriltag --> Lmk54
Ftr27 trk56 FeatureApriltag <--
m = ( 0.55 -0.4 1 7.1e-08 5.2e-08 -3.9e-08 1 )
Fac7 FactorApriltag --> Lmk56
CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1 <--
I [Est] = ( 0 0 0 0 0 0 ) @ 0x55e3cbe2e110
buffer size : 62 ; nbr of data samples : 61
delta preint : (0.000343 0.00354 -0.441 0 0 0 1 0.00339 0.0235 -2.94)
Ftr32 trk0 FeatureImu <--
m = ( 0.00034 0.0035 -0.44 0 0 0 1 0.0034 0.024 -2.9 )
Fac8 FactorImu --> Frm1 Cap3
Map
Lmk50 LandmarkApriltag <-- Fac4
P [Est] = ( 0.0465 -0.597 -1 ) @ 0x7fdfb001bd70
O [Est] = ( 1 0 0 0 ) @ 0x7fdfb8023c40
Lmk52 LandmarkApriltag <-- Fac5
P [Est] = ( 0.0465 -0.0971 -1 ) @ 0x7fdfe0010880
O [Est] = ( 1 3.44e-08 -2.6e-07 -7.4e-07 ) @ 0x55e3cbefe310
Lmk54 LandmarkApriltag <-- Fac6
P [Est] = ( 0.546 -0.0971 -1 ) @ 0x55e3cb806a70
O [Est] = ( 1 6.8e-08 8.7e-08 -1.25e-07 ) @ 0x7fdfb8022050
Lmk56 LandmarkApriltag <-- Fac7
P [Est] = ( 0.546 0.403 -1 ) @ 0x55e3cbe56990
O [Est] = ( 1 3.86e-08 5.21e-08 -7.06e-08 ) @ 0x55e3cb45ce30
---------------------------------------------------------------------
The method Problem::check()
The check() tool is intended for developers, and especially for developers involved in the core module of WOLF.
However, if you are writing plugins, you may want to ensure that what you do is fine in terms of the integrity of the WOLF tree.
We offer the method check() and a convenient alias, both in Problem:
class Problem [...]
{
public:
// check the WOLF tree integrity
bool check(bool verbose, std::ostream& stream) const;
// alias
bool check(int verbose_level = 0) const
{
return check((_verbose_level > 0), std::cout);
}
}
This method is similar to print() in some aspects,
but its main goal is to check that all pointers in the WOLF tree
are valid and that the bidirectional property is satisfied:
if A points to B, then B needs to also point to A.
So far, only two basic verbosity levels are implemented:
With
verbose > 0the method checks for pointer correctness and prints a pointer-oriented version of the whole WOLF tree for reference.With
verbose = 0the method just checks tree integrity, printing nothing.
In case the check is not passed, error messages will be created to help identifying the issue.
Examples
Quiet check
ProblemPtr problem_ptr;
[... fill in the tree ...]
if (not problem_ptr->check(0))
ERROR("There is something odd in Problem!");
Verbose check
ProblemPtr problem_ptr;
[... fill in the tree ...]
problem_ptr->check(1);
The result may look something like this, where:
The pointer of every WOLF node is shown.
The pointer of every state-block is shown, with the pointer of its local parametrization (see state block).
For every node, we check the pointers up in the tree (all ancestors).
For every factor, we check that the state blocks pointed at exist in the nodes pointed at.
All checks are bi-directional: if A has a pointer to B, then B must have a pointer to A,
A <--> B.One exception is that state blocks are pointed, but they do not point anywhere,
N --> sb.The second exception is that Captures point to Sensor, but the Sensors do not have pointers to their Captures,
Cap --> Sen.
Wolf tree integrity ---------------------
Prb @ 0x55729d047f90
Hrw @ 0x55729d048160
Sen2 @ 0x55729d0512d0
-> Prb @ 0x55729d047f90
-> Hrw @ 0x55729d048160
O sb @ 0x55729d04a1a0 (lp @ 0x55729d04d870)
P sb @ 0x55729d04b7e0
Prc2 @ 0x55729d051890 -> Sen2
-> Prb @ 0x55729d047f90
-> Sen2 @ 0x55729d0512d0
Trj @ 0x55729d048230
Frm8 @ 0x55729d04c000
-> Prb @ 0x55729d047f90
-> Trj @ 0x55729d048230
O sb @ 0x55729d056590 (lp @ 0x55729d04bef0)
P sb @ 0x55729d04c170
Cap10 @ 0x55729d04a2b0 -> Sen-
-> Prb @ 0x55729d047f90
-> Frm8 @ 0x55729d04c000
Ftr9 @ 0x55729d04ba70
-> Prb @ 0x55729d047f90
-> Cap10 @ 0x55729d04a2b0
Fac9 @ 0x55729d04b2f0 --> Abs.
-> Prb @ 0x55729d047f90
-> Ftr9 @ 0x55729d04ba70
sb @ 0x55729d056590 (lp @ 0x55729d04bef0) Frm8 found
Ftr10 @ 0x55729d050010
-> Prb @ 0x55729d047f90
-> Cap10 @ 0x55729d04a2b0
Fac10 @ 0x55729d04c660 --> Abs.
-> Prb @ 0x55729d047f90
-> Ftr10 @ 0x55729d050010
sb @ 0x55729d04c170 Frm8 found
Cap11 @ 0x55729d053ca0 -> Sen2
-> Prb @ 0x55729d047f90
-> Frm8 @ 0x55729d04c000
Map @ 0x55729d048330
--------------------------- Wolf tree OK